/*
 * SmtPlug.cpp
 *
 *  Created on: 2013-3-24
 *      Author: root
 */



#include "SmtPlug.h"
#include "smarthome-server.h"
#include <sys/syscall.h>
#define gettid() syscall(__NR_gettid)
using namespace std;
#define MAXCNTDOWN 60
#include <boost/progress.hpp>
void * start_udpsvr_4_dev(void * param)
{
	//设备线程3链接的数据库
			myDatabase mydatabase;
			pDevDB=&mydatabase;

			int i=0;
			for(i=0;i<10;i++)
			{
				//可能mysql服务还没启动
				if(pDevDB->open(HOST,USER,PASSWORD,DBNAME))
					break;
				else
				{
					sleep(1);
					DBG("retry connect database\n");
				}
			}




	SvrUdp4Dev socket;
	if(!socket.Create())
		return 0;
	pPlug->m_pdSocket=&socket;

	  struct sockaddr_in  addr_client;
	  HValue_t v;

		while(1)
		{
			DBG("waiting read\n\n");


				//boost::progress_timer t;

				//int recv_num = recvfrom(sockfd,recv_buf,sizeof(recv_buf),0,(struct sockaddr *)&addr_client,&client_len);
				int recv_num = pPlug->m_pdSocket->RecCmd(addr_client,v);

				struct timeval tv;
				gettimeofday(&tv,NULL);
				DBGS("%d",tv.tv_usec);

				unsigned char *p =(unsigned char*)&v;
				printf("从设备端口20131接收到 %d ,%s, %d \n",recv_num,inet_ntoa(addr_client.sin_addr),ntohs(addr_client.sin_port));

				for(int i=0;i<recv_num;i++)
					printf("%02x ",p[i]);
				printf("\n ");

				printf("len=%d,devid=%d,cmd=0x%x,usrid=%d\n",v.head.len,v.head.src.id,v.head.cmd,v.head.dst.id);


				if(recv_num!=v.head.len+sizeof(v.head))
					continue;

				if(!v.IsCRCCorrect())
				{
					cout<<"CRC 错误 dev"<<endl;
						continue;
				}
				DBG("crc=%d\n",v.head.crc);
				pPlug->ParseDevData(addr_client,v);


				struct timeval tv1;
				gettimeofday(&tv1,NULL);
				DBGS("%d",tv1.tv_usec-tv.tv_usec);
		}

		pDevDB->close();
		delete pDevDB;
}



void * start_udpsvr_4_usr(void * param)
{


	//用户线程链接数据库
			myDatabase myusrdatabase;
			pUsrDB=&myusrdatabase;

			int i=0;
			for(i=0;i<10;i++)
			{
				//可能mysql服务还没启动
				if(pUsrDB->open(HOST,USER,PASSWORD,DBNAME))
					break;
				else
				{
					sleep(1);
					DBG("retry connect database\n");
				}
			}



	SvrUdp4Usr socket;
	if(!socket.Create())
		return 0;
	pPlug->m_puSocket=&socket;

	  HValue_t v;
	  struct sockaddr_in  addr_client;
		while(1)
		{	DBG("waiting read\n\n");

			//int recv_num = recvfrom(sockfd,recv_buf,sizeof(recv_buf),0,(struct sockaddr *)&addr_client,&client_len);
			int recv_num = pPlug->m_puSocket->RecCmd(addr_client,v);

			struct timeval tv;
			gettimeofday(&tv,NULL);
			DBGS("%d",tv.tv_usec);


			unsigned char *p =(unsigned char*)&v;
			printf("从用户端口20132接收到 %d ,%s, %d \n",recv_num,inet_ntoa(addr_client.sin_addr),ntohs(addr_client.sin_port));
			for(int i=0;i<recv_num;i++)
				printf("%02x ",p[i]);
			printf("\n ");

			printf("len=%d,usrid=%d,cmd=0x%x,devid=%d\n",v.head.len,v.head.src.id,v.head.cmd,v.head.dst.id);

			if(recv_num!=v.head.len+sizeof(v.head))
				continue;

			if(!v.IsCRCCorrect())
			{
				cout<<"CRC 错误 usr"<<endl;
				continue;
			}

			//DBG("crc=%d\n",v.head.crc);
			pPlug->ParseUsrData(addr_client,v);

			struct timeval tv1;
			gettimeofday(&tv1,NULL);
			DBGS("%d",tv1.tv_usec-tv.tv_usec);
		}


		pUsrDB->close();
		delete pUsrDB;

}

#include <boost/progress.hpp>
void * start_count_down(void * param)
{




	while(1)
	{
		 for(IdAddrMap::iterator it = pPlug->m_usrIdAddrMap.begin(); it != pPlug->m_usrIdAddrMap.end(); it++)
		 {
			//cout<<it->first;
			//printf(" dev  %d\n",it->second.cntdown);
			if(it->second.cntdown>0)
			{
				it->second.cntdown--;
			}
			else if(it->second.cntdown<=0)
			{
				pPlug->m_usrIdAddrMap.erase(it);
			}
		 }




		 for(IdAddrMap::iterator it = pPlug->m_devIdAddrMap.begin(); it != pPlug->m_devIdAddrMap.end(); it++)
		 {
			//cout<<it->first;
			//printf(" usr  %d\n",it->second.cntdown);
			if(it->second.cntdown>0)
			{
				it->second.cntdown--;
			}
			else if(it->second.cntdown<=0)
			{
				pPlug->m_devIdAddrMap.erase(it);
			}
		 }


		 sleep(3);
	}
}


SmtPlug::SmtPlug() {
	// TODO Auto-generated constructor stub

	m_pthServerUsr=0;
	m_pthServerDev=0;
	m_usrIdAddrMap.clear();
	m_devIdAddrMap.clear();
}

SmtPlug::~SmtPlug() {
	// TODO Auto-generated destructor stub
}


int SmtPlug::StartWork()
{
	/*
	int res=0;
    if((res=pthread_mutexattr_init(&m_attr))!=0)
    {
    	printf("pthread_mutexattr_init ,res=%d\n",res);
    	exit(-1);
    }

    if((res=pthread_mutexattr_settype(&m_attr,PTHREAD_MUTEX_NORMAL))!=0)
    {
    	printf("pthread_mutexattr_settype ,res=%d\n",res);
    	exit(-1);
    }
    if((res= pthread_mutex_init(&m_workMutex, &m_attr))!=0)
    {
    	printf("pthread_mutex_init ,res=%d\n",res);
    	exit(-1);
    }


*/




	InitBind();
	InitDevInfo();
	InitUsrInfo();



	StartDevWork();
	StartUsrWork();

	StartCountDown();


}
void SmtPlug::StopWork()
{
	StopUsrWork();
	StopDevWork();

}

void SmtPlug::InitBind()
{
	char strSql[100];


	sprintf(strSql,"select * from Bind");
	myRecordSet pRecordset(pMainDB);
	uint32 usrId,devId=0;

	if(pRecordset.open(strSql))
	{
		 while(!pRecordset.isEOF())
		 {
			 pRecordset.getFieldValue("UsrId",usrId);
			 pRecordset.getFieldValue("DevId",devId);
			 cout<<"usrId="<<usrId<<",devId="<<devId<<endl;
			 m_usrdevMap.insert(make_pair(usrId,devId));
			 m_devusrMap.insert(make_pair(devId,usrId));
			 cout<<m_usrdevMap.size()<<endl;
			 pRecordset.moveNext();
		 }
		pRecordset.close();
	}


	//uint32 u32Value=value.value.u32Value;

}

void SmtPlug::InitDevInfo()
{
	char strSql[100];




	sprintf(strSql,"select * from DevInfo");
	myRecordSet pRecordset(pMainDB);
	uint32 devId=0;
	Pswd_t pswds;
	pswds.inSetingPswd=false;
	pswds.inSetingPswd=0;

	if(pRecordset.open(strSql))
	{
		 while(!pRecordset.isEOF())
		 {
			 pRecordset.getFieldValue("DevId",devId);
			 pRecordset.getFieldValue("Pswd",pswds.pswd);
			 cout<<"devId="<<devId<<",Pswd="<<pswds.pswd<<endl;
			 m_devIdPswdMap.insert(make_pair(devId,pswds));
			 cout<<m_devIdPswdMap.size()<<endl;
			 pRecordset.moveNext();
		 }
		pRecordset.close();
	}


}


void SmtPlug::InitUsrInfo()
{
	char strSql[100];


	sprintf(strSql,"select * from UsrInfo");
	myRecordSet pRecordset(pMainDB);
	uint32 usrId=0;
	Pswd_t pswds;
	pswds.inSetingPswd=false;
	pswds.cnt=0;
	if(pRecordset.open(strSql))
	{
		 while(!pRecordset.isEOF())
		 {
			 pRecordset.getFieldValue("UsrId",usrId);
			 pRecordset.getFieldValue("Pswd",pswds.pswd);
			 cout<<"usrId="<<usrId<<",Pswd="<<pswds.pswd<<endl;
			 m_usrIdPswdMap.insert(make_pair(usrId,pswds));
			 cout<<m_usrIdPswdMap.size()<<endl;
			 pRecordset.moveNext();
		 }
		pRecordset.close();
	}



}
int SmtPlug::StartDevWork()
{
	 int ret=ESRCH;
	 if(m_pthServerDev)
		 ret=pthread_kill(m_pthServerDev,0);
	if(ret==ESRCH)
	{
		pthread_create(&m_pthServerDev,NULL,start_udpsvr_4_dev,this);
		cout<<"Start server for device..."<<endl;
		cout<<"Server thread ID:"<<m_pthServerDev<<endl;
	}
	else
	{
		cout<<"Server is already run!"<<endl;
		cout<<"Server thread ID:"<<m_pthServerDev<<endl;
		return -1;
	}

   return 0;
}

int SmtPlug::StartUsrWork()
{
	 int ret=ESRCH;
	 if(m_pthServerUsr)
		 ret=pthread_kill(m_pthServerUsr,0);
	if(ret==ESRCH)
	{
		pthread_create(&m_pthServerUsr,NULL,start_udpsvr_4_usr,this);
		cout<<"Start server for device..."<<endl;
		cout<<"Server thread ID:"<<m_pthServerUsr<<endl;
	}
	else
	{
		cout<<"Server is already run!"<<endl;
		cout<<"Server thread ID:"<<m_pthServerUsr<<endl;
		return -1;
	}

   return 0;
}

int SmtPlug::StartCountDown()
{
	 int ret=ESRCH;
	 if(m_pthCountDown)
		 ret=pthread_kill(m_pthCountDown,0);
	if(ret==ESRCH)
	{
		pthread_create(&m_pthCountDown,NULL,start_count_down,this);
		cout<<"Start countdown ..."<<endl;
		cout<<"countdown ID:"<<m_pthCountDown<<endl;
	}
	else
	{
		cout<<"countdown is already run!"<<endl;
		cout<<"countdown thread ID:"<<m_pthCountDown<<endl;
		return -1;
	}

   return 0;
}

void SmtPlug::StopUsrWork()
{

	int ret=ESRCH;
	if(m_pthServerUsr)
	ret=pthread_kill(m_pthServerUsr,0);
	if(ret!=ESRCH)
	{
		pthread_cancel(m_pthServerUsr);
		cout<<"Stop command server."<<endl;
	}
	m_puSocket->Close();

}


void SmtPlug::StopDevWork()
{

	int ret=ESRCH;
	if(m_pthServerDev)
	ret=pthread_kill(m_pthServerDev,0);
	if(ret!=ESRCH)
	{
		pthread_cancel(m_pthServerDev);
		cout<<"Stop command server."<<endl;
	}
	m_pdSocket->Close();

}

void SmtPlug::StopCountDown()
{

	int ret=ESRCH;
	if(m_pthCountDown)
	ret=pthread_kill(m_pthCountDown,0);
	if(ret!=ESRCH)
	{
		pthread_cancel(m_pthCountDown);
		cout<<"Stop countdown server."<<endl;
	}

}

int SmtPlug::ParseDevData(struct sockaddr_in &addr,HValue_t &value)
{

	uint32 devId=value.head.src.id;
	uint32 usrId=value.head.dst.id;
	uint16 cmd=value.head.cmd;

	//DBG("devId= %d \n",devId);
	//DBG("usrId= %d \n",usrId);
//验证密码,m_devIdPswdMap
	IdPswdMap::iterator it = m_devIdPswdMap.find(devId);
	if (it == m_devIdPswdMap.end())
	{
		DBGS("错误的id");
		return -1;//错误的id
	}
	else
	{
		//如果是初始密码，马上修改
		if(strcmp(value.head.src.pswd,"123456789012")==0)
		{


			//如果已经处于修改密码状态,不执行修改，也拒绝服务.5次机会
			if(it->second.inSetingPswd==true  )
			{
				if(it->second.cnt < 5)
				{
					DBGS("初始密码,处于修改中,拒绝服务");
					it->second.cnt++;

					// 如果设置失败，yunxu再次设置
					if(cmd==SET_DEV_PSWD && value.value.szValue[0]==SMT_FAILED)
					{
						DBGS("初始密码,设置失败");
						it->second.inSetingPswd=false;
						it->second.cnt=0;
					}
					return 0;
				}
				else
				{
					it->second.cnt =0;
					it->second.inSetingPswd=false;
					return 0;
				}
			}


			DBGS("初始密码，修改");
			//产生密码并回复
			HValue res;
			memset(&res,0,sizeof(res));

			struct timeval tv;
			for(uint8 i=0;i<12;i++)
			{
				gettimeofday(&tv,NULL);
				srand(tv.tv_usec);
				res.value.szValue[i]=48+rand()%10;//'0'-'9'
				printf("%d: %c--%x \n",__LINE__,res.value.szValue[i],res.value.szValue[i]);
			}

			res.value.szValue[12]=0;
			printf("%d: %s\n",__LINE__,res.value.szValue);
			//update map
			it->second.pswd=(char*)res.value.szValue;
			it->second.inSetingPswd=true;
			it->second.cnt=0;


			res.head.dst=value.head.src;
			res.head.cmd=SET_DEV_PSWD;
			res.head.len=13;

			m_pdSocket->SendCmd(addr,res);

			return 0;
		}
		else
		{
			if(strcmp(value.head.src.pswd,it->second.pswd.c_str())!=0)
			{
				DBGS("错误的密码:%s,应该是%s",value.head.src.pswd,it->second.pswd.c_str());
				return -2;//错误的密码
			}
			else
				DBGS("正确的密码:%s",value.head.src.pswd);

			if(it->second.inSetingPswd==true)
			{
				//if(cmd==SET_DEV_PSWD && value.value.szValue[0]==SMT_SUCCESS)
				{

					//更新数据库密码,map中已经保存有新密码
					char strSql[300];
					sprintf(strSql,"Update DevInfo Set Pswd='%s' where DevId=%d",it->second.pswd.c_str(),devId);
					cout<<strSql<<endl;


					//update mysql
					if(pDevDB->exec(strSql))
					{
						it->second.inSetingPswd=false;
						it->second.cnt=0;
						DBGS("初始密码,修改完毕");
					}



				}
			}

		}
	}


//bind map ,m_devIdAddrMap
	Addr_t dev;
	memset(&dev,0,sizeof(dev));
	dev.addr=addr;
	dev.cntdown=MAXCNTDOWN;
	m_devIdAddrMap[devId]=dev;


	//先找到用户的网络地址
	struct sockaddr_in *pusrAddr;

	IdAddrMap::iterator it2;
	if(usrId==0xffffffff)//如果设备在群发信息
	{
		 for(IdMap::iterator it = m_devusrMap.find(devId); it !=m_devusrMap.end(); it++)//遍历绑定过该设备的所有用户
		{
		//	std::cout<<__LINE__<<" "<<it->first<<","<<it->second<<endl;

			usrId=it->second;
			it2 = m_usrIdAddrMap.find(usrId);//在所有这些用户中找到第一个在线的用户（如果有多个绑定过该设备的用户同时在线，只发给第一个）
			if (it2 != m_usrIdAddrMap.end())
			{
				pusrAddr =&it2->second.addr;
				value.head.dst.id=usrId;
				break;
			}
			usrId=0xffffffff;
			pusrAddr=0;
		}
	}
	else if(usrId!=0xffffffff)//如果设备指定了用户
	{
		it2 = m_usrIdAddrMap.find(usrId);
		if (it2 != m_usrIdAddrMap.end())
			pusrAddr=&it2->second.addr;
		else
			pusrAddr =0;
	}

//填充yonghu密码
	IdPswdMap::iterator it1 = m_usrIdPswdMap.find(usrId);
	if (it1 != m_usrIdPswdMap.end())
	{
		strcpy(value.head.dst.pswd,it1->second.pswd.c_str());
	}



//处理服务
	switch (cmd)
	{
		case BEAT:
			break;

		case SET_DEV_PSWD:
			break;


		case UP_ALL_VALUE://需要给设备返回信号
		{

			LogDevData(addr,value);

			HValue res;
			memset(&res,0,sizeof(res));
			res.head.dst=value.head.src;
			res.head.src.id=value.head.dst.id;
			res.head.cmd=UP_ALL_VALUE;
			res.head.len=1;
			res.value.szValue[0]=SMT_SUCCESS;

			m_pdSocket->SendCmd(addr,res);

			if(pusrAddr)
				m_puSocket->SendCmd(*pusrAddr,value);


		}
			break;

		case UP_ALL_VALUE_FROM_FLASH://需要给设备返回信号
		{
			LogDevData(addr,value);

			DataFromFlash_t *pData=(DataFromFlash_t*)value.value.szValue;
			HValue res;
			memset(&res,0,sizeof(res));
			res.head.dst=value.head.src;
			res.head.cmd=UP_ALL_VALUE_FROM_FLASH;
			res.head.len=1;
			res.value.u32Value=(uint32)pData->nvItemPos;
			m_pdSocket->SendCmd(addr,res);


		}
			break;

	    //设备端口收到CX_ALL_VALUE命令，则是设备回复客户的CX_ALL_VALUE，直接转发给客户
		case CX_ALL_VALUE://不返回信号
			LogDevData(addr,value);
			if(pusrAddr)
				m_puSocket->SendCmd(*pusrAddr,value);

			break;

		default:
			LogDevData(addr,value);
			if(pusrAddr)
				m_puSocket->SendCmd(*pusrAddr,value);

			break;

	}
	return 0;
}

int SmtPlug::ParseUsrData(struct sockaddr_in &addr,HValue_t &value)
{

	uint32 usrId=value.head.src.id;
	uint32 devId=value.head.dst.id;
	uint16 cmd=value.head.cmd;

//用户注册不必验证密码
	if(cmd==USR_REG)
	{

		ProccessUsrReg(addr,value);
		LogUsrData(addr,value);
		return 0;
	}


	uint32 err=0;
//验证密码,m_devIdPswdMap
	IdPswdMap::iterator it = m_usrIdPswdMap.find(usrId);
	if (it == m_usrIdPswdMap.end())
	{
		err=USR_INVALIDE;
	}
	else
	{
		//DBG("value.head.src.pswd=%s\n",value.head.src.pswd);
		//DBG("it->second.c_str()=%s\n",it->second.pswd.c_str());
		if(strcmp(value.head.src.pswd,it->second.pswd.c_str())!=0)
		{
			err=PSWD_INVALIDE;//错误的密码
		}

	}

	if(err!=0)
	{
		HValue res;
		memset(&res,0,sizeof(res));
		res.head.dst=value.head.src;

		res.head.len=1;
		res.head.cmd=USR_LOGIN;
		res.value.szValue[0]=err;

		cout<<res.head.len<<endl;
		cout<<res.head.dst.id<<endl;
		m_puSocket->SendCmd(addr,res);
		return err;
	}



//bind map ,m_usrIdAddrMap
	Addr_t dev;
	memset(&dev,0,sizeof(dev));
	dev.addr=addr;
	dev.cntdown=MAXCNTDOWN;
	m_usrIdAddrMap[usrId]=dev;


//填充设备密码
	IdPswdMap::iterator it1 = m_devIdPswdMap.find(devId);
	if (it1 != m_devIdPswdMap.end())
	{
		strcpy(value.head.dst.pswd,it1->second.pswd.c_str());
	}

//找到设备的网络地址
	struct sockaddr_in *pdevAddr;
	IdAddrMap::iterator it2 = m_devIdAddrMap.find(devId);
	if (it2 == m_devIdAddrMap.end())
		pdevAddr=0;
	else
		pdevAddr =&it2->second.addr;
	printf("pdevAddr=%x\n",pdevAddr);

	//DBG("ip=%s\n",inet_ntoa(pdevAddr->sin_addr));
	//DBG("port=%d\n",ntohs(pdevAddr->sin_port));

	switch (cmd)
	{



	//管理员添加设备
		case ADMIN_DEV_ADD:


			if(usrId==1)
			{
				LogUsrData(addr,value);
				ProccessAdminDevAdd(addr,value);
			}
			break;

	//管理员删除设备
		case ADMIN_DEV_DELETE:
			if(usrId==1)
			{
				LogUsrData(addr,value);
				ProccessAdminDevDelete(addr,value);
			}
			break;

	//管理员删除普通用户
		case ADMIN_USR_DELETE:
			if(usrId==1)
			{
				LogUsrData(addr,value);
				ProccessAdminUsrDelete(addr,value);
			}
			break;

	//管理员添加普通用户
		case ADMIN_USR_ADD:
			if(usrId==1)
			{
				LogUsrData(addr,value);
				ProccessAdminUsrAdd(addr,value);
			}
			break;

	//普通用户登录
		case USR_LOGIN:
			LogUsrData(addr,value);
			ProccessUsrLogin(addr,value);

			break;
	//普通用户修改密码
		case USR_MODIFY_PSWD:

			LogUsrData(addr,value);
			ProccessUsrModifyPswd(addr,value);

			break;
   //普通用户注册
		case USR_REG:

			LogUsrData(addr,value);
			ProccessUsrReg(addr,value);

			break;
//普通用户绑定设备
		case USR_BIND_DEV:
			LogUsrData(addr,value);
			ProccessUsrBindDev(addr,value);

			break;
//普通用户解除绑定设备
		case USR_UNBIND_DEV:

			LogUsrData(addr,value);
			ProccessUsrUnBindDev(addr,value);

			break;

		case FORCE_DEV_OFFLINE://用户查询设备是够在线，直接回复即可
			LogUsrData(addr,value);

			if(pdevAddr)
				value.value.u32Value=1;
			else
				value.value.u32Value=0;
			ProccessForceDevOffline(addr,value);

			break;

//普通用户查询设备是否在线
		case CX_DEV_ISONLINE://用户查询设备是够在线，直接回复即可
			LogUsrData(addr,value);

			if(pdevAddr)
				value.value.u32Value=1;
			else
				value.value.u32Value=0;
			ProccessCxDevIsonline(addr,value);

			break;
//普通用户对设备进行操作
		case SET_ON_RELAY:
		case SET_OFF_RELAY:
		case SET_ON_DO16:
		case SET_OFF_DO16:
		case SET_ON_DO20:
		case SET_OFF_DO20:
		case SET_ON_DO00:
		case SET_OFF_DO00:
		case SET_ON_DO01:
		case SET_OFF_DO01:
		case SET_ON_DO06:
		case SET_OFF_DO06:
		case SET_ON_DO07:
		case SET_OFF_DO07:
		case SET_DEV_POLL_FREQ:
			//
			LogUsrData(addr,value);
			if(pdevAddr==0)//not online
			{
				DBG("\n");
				HValue res;
				memset(&res,0,sizeof(res));
				res.head.len=2;
				res.head.cmd=cmd;
				res.head.dst=value.head.src;
				res.value.szValue[0]=SMT_DEV_OFFLINE;
				m_puSocket->SendCmd(addr,res);

			}
			else
			{
				m_pdSocket->SendCmd(*pdevAddr,value);
			}

			break;


		default:
			LogUsrData(addr,value);
			if(pdevAddr)
				m_pdSocket->SendCmd(*pdevAddr,value);

			break;
		DBG("\n");
	}
}

void SmtPlug::ProccessCxDevIsonline(struct sockaddr_in &addr,HValue_t &value)
{
	HValue res;
	memset(&res,0,sizeof(res));
	res.head.len=0;
	if(value.value.u32Value == 1)
		res.head.cmd=UP_DEV_ISONLINE_ON;
	else
		res.head.cmd=UP_DEV_ISONLINE_OFF;
	res.head.dst=value.head.src;

	m_puSocket->SendCmd(addr,res);

}

void SmtPlug::ProccessForceDevOffline(struct sockaddr_in &addr,HValue_t &value)
{

	if(value.value.u32Value == 1)
	{
		IdAddrMap::iterator it = m_devIdAddrMap.find(value.head.dst.id);
		if (it != m_devIdAddrMap.end() )
			m_devIdAddrMap.erase(it);
	}

	HValue res;
	memset(&res,0,sizeof(res));
	res.value.szValue[0]=SMT_SUCCESS;
	res.head.len=1;
	res.head.cmd=FORCE_DEV_OFFLINE;
	res.head.dst=value.head.src;




	m_puSocket->SendCmd(addr,res);

}


int SmtPlug::ProccessUsrBindDev(struct sockaddr_in &addr,HValue_t &value)
{
	uint32 devId=value.head.dst.id;
	uint32 usrId=value.head.src.id;

	HValue res;
	memset(&res,0,sizeof(res));
	res.head.len=4;
	res.head.cmd=USR_BIND_DEV;
	res.head.src=value.head.dst;
	res.head.dst=value.head.src;
	DBG("\n");
	int err=SMT_SUCCESS;

	IdPswdMap::iterator it = m_devIdPswdMap.find(devId);
	if (it == m_devIdPswdMap.end() )
	{
		err= USR_BIND_DEV_INVALID_DEV;//错误的id
		res.value.u32Value=err;
	}
	else
	{
		// 查看是否已经绑定过
		 for(IdMap::iterator it = m_usrdevMap.find(usrId); it !=m_usrdevMap.end(); ++it)
		{

			 std::cout<<it->first<<","<<it->second<<endl;
			 if(it->first!=usrId)
				 break;

			 if(it->second==devId)
			 {
				 err= USR_BIND_DEV_ALREADY_BIND;
				 res.value.u32Value=err;
				 break;
			 }

		}

	}
	DBG("\n");
	 if(err == SMT_SUCCESS)
	 {
		DBG("\n");
		char strSql[300];
		sprintf(strSql,"Insert into Bind Values ('%s','%s',%d,%d)",DateTime::GetNowDate().c_str(),DateTime::GetNowTime().c_str(),usrId,devId);
		cout<<strSql<<endl;




		if(!pUsrDB->exec(strSql))
		{
			cout<<"AddErrorLog failure!"<<endl;
			err= SMT_FAILED;
			res.value.u32Value=err;
		}



		m_usrdevMap.insert(make_pair(usrId,devId));
		m_devusrMap.insert(make_pair(devId,usrId));
	 }

	res.value.u32Value=err;
	m_puSocket->SendCmd(addr,res);
	return err;

}



int SmtPlug::ProccessUsrUnBindDev(struct sockaddr_in &addr,HValue_t &value)
{

	uint32 devId=value.head.dst.id;
	uint32 usrId=value.head.src.id;


	HValue res;
	memset(&res,0,sizeof(res));
	res.head.len=1;
	res.head.cmd=USR_UNBIND_DEV;
	res.head.src=value.head.dst;
	res.head.dst=value.head.src;
	DBG("\n");
	int err=SMT_SUCCESS;

/*
	IdPswdMap::iterator it = m_devIdPswdMap.find(devId);
	if (it == m_devIdPswdMap.end() )
	{
		err= USR_BIND_DEV_INVALID_DEV;//错误的id
		res.value.szValue[0]=err;
	}

	else
	*/
	{
		// 从m_usrdevMap解除
		 for(IdMap::iterator it = m_usrdevMap.find(usrId); it !=m_usrdevMap.end(); it++)
		{
			 std::cout<<it->first<<"--,"<<it->second<<endl;
			 if(it->first!=usrId)
				 break;

			 if(it->second==devId)
			 {
				 m_usrdevMap.erase(it);

				 err= SMT_SUCCESS;
				 res.value.szValue[0]=err;
				 break;
			 }
		}

		// 从m_devusrMap解除
		 for(IdMap::iterator it = m_devusrMap.find(devId); it !=m_usrdevMap.end(); it++)
		{
			 std::cout<<it->first<<",--"<<it->second<<endl;
			 if(it->first!=devId)
				 break;


			 if(it->second==usrId)
			 {
				 m_devusrMap.erase(it);

				 err= SMT_SUCCESS;
				 res.value.szValue[0]=err;
				 break;
			 }

		}



	}




    std::cout<<"----"<<endl;
	 for(IdMap::iterator it = m_devusrMap.begin();it !=m_usrdevMap.end(); ++it)
	{
		 std::cout<<it->first<<","<<it->second<<endl;
	}
	 std::cout<<"----"<<endl;
	 for(IdMap::iterator it = m_usrdevMap.begin();it !=m_usrdevMap.end(); ++it)
	{
		 std::cout<<it->first<<","<<it->second<<endl;
	}
	 std::cout<<"----"<<endl;


	 if(err == SMT_SUCCESS)
	 {

		DBG("\n");
		char strSql[300];
		sprintf(strSql,"delete from Bind where UsrId=%d and DevId=%d",usrId,devId);
		cout<<strSql<<endl;



		if(!pUsrDB->exec(strSql))
		{
			cout<<"AddErrorLog failure!"<<endl;
			err= SMT_FAILED;
			res.value.szValue[0]=err;
		}


	 }

	res.value.szValue[0]=err;
	m_puSocket->SendCmd(addr,res);
	return err;


}


void SmtPlug::ProccessAdminDevAdd(struct sockaddr_in &addr,HValue_t &value)
{

	struct timeval tv;


	int err=SMT_SUCCESS;
	char strSql[300];

	AdminId_t *pAdminId=(AdminId_t*)value.value.szValue;
	uint32 devId= pAdminId->firstId;

DBG("\n");

	while(devId <= pAdminId->lastId )
	{
		 if(devId < 0)
			 err=SMT_FAILED;

		if(err==SMT_FAILED)
				break;

		IdPswdMap::iterator it = m_devIdPswdMap.find(devId);


		if (it == m_devIdPswdMap.end() )
		{
			gettimeofday(&tv,NULL);
			sprintf(strSql,"Insert into DevInfo (AddDate,AddTime,AddTimeUsec,DevId,Pswd) Values ('%s','%s',%d,%d,'%s')",DateTime::GetNowDate().c_str(),DateTime::GetNowTime().c_str(),tv.tv_usec,devId,"123456789012");
			cout<<strSql<<endl;

			if(!pUsrDB->exec(strSql))
			{
				cout<<"AddErrorLog failure!"<<endl;
				err= SMT_FAILED;
			}
			else//数据库添加成功
			{
				Pswd_t pswdt;
				pswdt.inSetingPswd=false;
				pswdt.cnt=0;
				pswdt.pswd="123456789012";
				m_devIdPswdMap.insert(make_pair(devId,pswdt));
			}




		}

		devId++;

	}



	HValue res;
	memset(&res,0,sizeof(res));
	res.head.len=1;
	res.head.cmd=ADMIN_DEV_ADD;
	res.head.src=value.head.dst;
	res.head.dst=value.head.src;
	res.value.szValue[0]=err;

	m_puSocket->SendCmd(addr,res);



}
void SmtPlug::ProccessAdminDevDelete(struct sockaddr_in &addr,HValue_t &value)
{

	struct timeval tv;
	gettimeofday(&tv,NULL);

	int err=SMT_SUCCESS;
	char strSql[300];


	AdminId_t *pAdminId=(AdminId_t*)value.value.szValue;

	uint32 devId= pAdminId->firstId;





	while(devId <= pAdminId->lastId )
	{
		 if(devId < 0)
			 err=SMT_FAILED;

		if(err==SMT_FAILED)
			break;
		IdPswdMap::iterator it = m_devIdPswdMap.find(devId);
		if (it != m_devIdPswdMap.end() )
		{
			sprintf(strSql,"delete from DevInfo where DevId = %d ",devId);
			cout<<strSql<<endl;

			if(!pUsrDB->exec(strSql))
			{
				cout<<"AddErrorLog failure!"<<endl;
				err= SMT_FAILED;
				break;
			}

			//删除绑定表中的项目
			{

				//从m_devusrMap中删除所有的first是devId的元素
				 for(IdMap::iterator it2 = m_devusrMap.find(devId); it2 !=m_devusrMap.end(); it2++)
				{
					 std::cout<<it2->first<<","<<it2->second<<endl;

					 if(it2->first!=devId)

						break;

					 uint32 usrId = it2->second;

					 //删除数据库中记录
						sprintf(strSql,"delete from Bind where DevId = %d and UsrId = %d",devId,usrId);
						cout<<strSql<<endl;

						if(!pUsrDB->exec(strSql))
						{
							cout<<"AddErrorLog failure!"<<endl;
							err= SMT_FAILED;
							break;
						}

						 //从m_usrdevMap中删除
						 for(IdMap::iterator it3 = m_usrdevMap.find(usrId); it3 !=m_usrdevMap.end(); it3++)
						 {
							 if(it3->first!=usrId)
								 break;

							 if(it3->second==devId)
							 {
								 m_usrdevMap.erase(it3);
							 }
						 }

					 m_devusrMap.erase(it2);
				}


			}




			m_devIdPswdMap.erase(it);

		}

		devId++;

	}



	HValue res;
	memset(&res,0,sizeof(res));
	res.head.len=1;
	res.head.cmd=ADMIN_DEV_DELETE;
	res.head.src=value.head.dst;
	res.head.dst=value.head.src;
	res.value.szValue[0]=err;


	m_puSocket->SendCmd(addr,res);


    std::cout<<"----"<<endl;
	 for(IdMap::iterator it = m_devusrMap.begin();it !=m_usrdevMap.end(); ++it)
	{
		 std::cout<<it->first<<","<<it->second<<endl;
	}
	 std::cout<<"----"<<endl;
	 for(IdMap::iterator it = m_usrdevMap.begin();it !=m_usrdevMap.end(); ++it)
	{
		 std::cout<<it->first<<","<<it->second<<endl;
	}
	 std::cout<<"----"<<endl;

}


void SmtPlug::ProccessAdminUsrAdd(struct sockaddr_in &addr,HValue_t &value)
{


	struct timeval tv;


	int err=SMT_SUCCESS;
	char strSql[300];

	AdminId_t *pAdminId=(AdminId_t*)value.value.szValue;
	uint32 usrId= pAdminId->firstId;





	while(usrId <= pAdminId->lastId )
	{
		 if(usrId < 0)
			 err=SMT_FAILED;

		if(err==SMT_FAILED)
				break;

		IdPswdMap::iterator it = m_usrIdPswdMap.find(usrId);
		if (it == m_usrIdPswdMap.end() )
		{
			gettimeofday(&tv,NULL);
			sprintf(strSql,"Insert into UsrInfo (AddDate,AddTime,AddTimeUsec,UsrId,Pswd) Values ('%s','%s',%d,%d,'%s')",DateTime::GetNowDate().c_str(),DateTime::GetNowTime().c_str(),tv.tv_usec,usrId,"123456789012");
			cout<<strSql<<endl;
			if(!pUsrDB->exec(strSql))
			{
				cout<<"AddErrorLog failure!"<<endl;
				err= SMT_FAILED;
			}
			else//数据库添加成功
			{
				Pswd_t pswdt;
				pswdt.inSetingPswd=false;
				pswdt.cnt=0;
				pswdt.pswd="123456789012";
				m_usrIdPswdMap.insert(make_pair(usrId,pswdt));
			}

		}

		usrId++;

	}



	HValue res;
	memset(&res,0,sizeof(res));
	res.head.len=1;
	res.head.cmd=ADMIN_USR_ADD;
	res.head.src=value.head.dst;
	res.head.dst=value.head.src;
	res.value.szValue[0]=err;

	m_puSocket->SendCmd(addr,res);



}


void SmtPlug::ProccessAdminUsrDelete(struct sockaddr_in &addr,HValue_t &value)
{

	struct timeval tv;
	gettimeofday(&tv,NULL);


	int err=SMT_SUCCESS;
	char strSql[300];


	AdminId_t *pAdminId=(AdminId_t*)value.value.szValue;
	uint32 usrId= pAdminId->firstId;




	while(usrId <= pAdminId->lastId )
	{
		 if(usrId < 100)
			 err=SMT_FAILED;

		if(err==SMT_FAILED)
			break;

		IdPswdMap::iterator it = m_usrIdPswdMap.find(usrId);
		if (it != m_usrIdPswdMap.end() )
		{
			sprintf(strSql,"delete from UsrInfo where UsrId =%d ",usrId);

			cout<<strSql<<endl;


			if(!pUsrDB->exec(strSql))
			{
				cout<<"AddErrorLog failure!"<<endl;
				err=SMT_FAILED;
				break;
			}


			//删除绑定表中的项目
			{
				//从m_usrdevMap中删除所有的first是usrId的元素


				 for(IdMap::iterator it2 = m_usrdevMap.find(usrId); it2 !=m_usrdevMap.end(); it2++)
				{
					 std::cout<<it2->first<<","<<it2->second<<endl;
					 if(it2->first!=usrId)
						 break;

					 uint32 devId = it2->second;

					 //删除数据库中记录
						sprintf(strSql,"delete from Bind where DevId = %d and UsrId = %d",devId,usrId);
						cout<<strSql<<endl;
						if(!pUsrDB->exec(strSql))
						{
							cout<<"AddErrorLog failure!"<<endl;
							err= SMT_FAILED;
							break;
						}

						 //从m_devusrMap中删除
						 for(IdMap::iterator it3 = m_devusrMap.find(devId); it3 !=m_devusrMap.end(); it3++)
						 {
							 if(it3->first!=devId)
								 break;

							 if(it3->second==usrId)
							 {
								 m_devusrMap.erase(it3);
							 }
						 }

						 m_usrdevMap.erase(it2);
				}
			}



			m_usrIdPswdMap.erase(it);

		}


		usrId++;

	}


	HValue res;
	memset(&res,0,sizeof(res));
	res.head.len=1;
	res.head.cmd=ADMIN_USR_DELETE;
	res.head.src=value.head.dst;
	res.head.dst=value.head.src;
	res.value.szValue[0]=err;

	m_puSocket->SendCmd(addr,res);

    std::cout<<"----"<<endl;
	 for(IdMap::iterator it = m_devusrMap.begin();it !=m_usrdevMap.end(); ++it)
	{
		 std::cout<<it->first<<","<<it->second<<endl;
	}
	 std::cout<<"----"<<endl;
	 for(IdMap::iterator it = m_usrdevMap.begin();it !=m_usrdevMap.end(); ++it)
	{
		 std::cout<<it->first<<","<<it->second<<endl;
	}
	 std::cout<<"----"<<endl;
}

void SmtPlug::ProccessUsrModifyPswd(struct sockaddr_in &addr,HValue_t &value)
{

	DBG("\n");
	uint32 usrId=value.head.src.id;

	HValue res;
	memset(&res,0,sizeof(res));
	res.head.dst=value.head.src;

	cout<<"usrId "<<usrId<<endl;
	IdPswdMap::iterator it = m_usrIdPswdMap.find(usrId);
	if (it != m_usrIdPswdMap.end())
	{
		std::cout<<it->first<<","<<it->second.pswd<<endl;
		char strSql[300]={0};
		sprintf(strSql,"Update UsrInfo Set Pswd='%s' where UsrId=%d",value.value.szValue,usrId);
		cout<<strSql<<endl;





		if(!pUsrDB->exec(strSql))
		{
			cout<<"AddErrorLog failure!"<<endl;
			res.value.szValue[0]= SMT_FAILED;
		}
		else
		{

		 it->second.pswd=(char*)value.value.szValue;
		 res.value.szValue[0]=SMT_SUCCESS;
		}




	}
	else
	{
		res.value.szValue[0]=SMT_FAILED;
	}

	res.head.cmd=USR_MODIFY_PSWD;
	m_puSocket->SendCmd(addr,res);

}

void SmtPlug::ProccessUsrLogin(struct sockaddr_in &addr,HValue_t &value)
{


	DBG("\n");
	uint32 usrId=value.head.src.id;

	HValue res;
	memset(&res,0,sizeof(res));
	res.head.dst=value.head.src;


	uint32 devId[100]={0};
	int i=0;
	cout<<"usrId "<<usrId<<endl;
	IdMap::iterator it = m_usrdevMap.find(usrId);
	for(; it !=m_usrdevMap.end(); it++)
	{
		 std::cout<<it->first<<","<<it->second<<endl;
		 if(it->first!=usrId)
			 break;
		 devId[i++]=it->second;

	}

	res.value.szValue[0]=SMT_SUCCESS;
	memcpy(&res.value.szValue[1],devId,i*4);
	res.head.len=i*4+1;
	res.head.cmd=USR_LOGIN;
	m_puSocket->SendCmd(addr,res);

}

int SmtPlug::ProccessUsrReg(struct sockaddr_in &addr,HValue_t &value)
{

	RegInfo_t *pReg=(RegInfo_t *)value.value.szValue;
	printf("%s\n",pReg->eMail);
	printf("%s\n",pReg->pswd);
	printf("%s\n",pReg->usrName);
	HValue res;
	memset(&res,0,sizeof(res));

	char strSql[300];
	uint32 usrId=0;
	 while(1)
	 {
			struct timeval tv;
			gettimeofday(&tv,NULL);
			srand(tv.tv_usec);

			usrId=100000+rand()%899999;//100000-999999
			printf("%d\n",usrId);

			sprintf(strSql,"select * from UsrInfo where UsrId=%d ",usrId);
			cout<<strSql<<endl;


			myRecordSet pRecordset(pUsrDB);
			if(pRecordset.open(strSql))
			{
				 if(!pRecordset.isEOF())
				 {
					 pRecordset.close();

					 continue;
				 }
				pRecordset.close();

				break;
			}

	 }

		struct timeval tv;
		gettimeofday(&tv,NULL);

	sprintf(strSql,"insert into UsrInfo(AddDate,AddTime,AddTimeUsec,UsrId,Pswd,UsrName,Email) Values('%s','%s',%d,%d,'%s','%s','%s')",
			DateTime::GetNowDate().c_str(),
			DateTime::GetNowTime().c_str(),
			tv.tv_usec,
			usrId,
			pReg->pswd,
			pReg->usrName,
			pReg->eMail

			);
		cout<<strSql<<endl;




		if(!pUsrDB->exec(strSql))
		{
			cout<<"AddErrorLog failure!"<<endl;
			res.value.szValue[0]=SMT_FAILED;
		}else
		{
			res.value.szValue[0]=SMT_SUCCESS;


			Pswd_t pswds;
			pswds.inSetingPswd=false;
			pswds.cnt=0;
			pswds.pswd=(char*)pReg->pswd;

			m_usrIdPswdMap.insert(make_pair(usrId,pswds));
		}
			cout<<"success"<<endl;

		res.head.dst=value.head.src;

		res.head.len=1;
		res.head.cmd=USR_REG;
		res.head.dst.id=usrId;
		strcpy((int8*)value.head.dst.pswd,(int8*)pReg->pswd);

		cout<<res.head.len<<endl;

		cout<<res.head.dst.id<<endl;
		m_puSocket->SendCmd(addr,res);
return 0;

}

int SmtPlug::FillCountDown(uint32 devId)
{
	char strSql[200];
	sprintf(strSql,"Update DevInfo set CountDown =10 ,status =1 where devId=%d",devId);
	if(false==pDevDB->exec(strSql))
		return 0;
}

int SmtPlug::FindUsrAndPswd(Info_t &info)
{

	string sPswdSrc=info.pswd;
	string sPswd;
	char strSql[200];
	sprintf(strSql,"Select * From DevInfo Where DevID=%d",info.id);
	cout<<strSql<<endl;
	myRecordSet pRecordset(pDevDB);
	if(pRecordset.open(strSql))
	{

		 if(!pRecordset.isEOF())
		 {

			 pRecordset.getFieldValue("Pswd",sPswd);

			 if(strncmp(sPswd.c_str(),info.pswd,12)==0)
			 {
				 pRecordset.close();
				 return 0;//devid and pswd all are right
			 }
			 else
			 {
				 pRecordset.close();
				 return -2;//pswd is incorrect
			 }
		 }
		 pRecordset.close();
		 return -1;//no this devid
	}
	return -3;//other err

}


/**
 * function 可打印字符串转换为字节数据
 * 如："C8329BFD0E01" --> {0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01}
 * 输入: pSrc - 源字符串指针
 * 		nSrcLength - 源字符串长度
 * 输出: pDst - 目标数据指针
 * 返回: 目标数据长度
 */
int SmtPlug::string2Bytes(const uint8* pSrc, uint8* pDst, int nSrcLength)
{
	for (int i = 0; i < nSrcLength; i += 2)
	{
		// 输出高4位
		if ((*pSrc >= '0') && (*pSrc <= '9'))
		{
			*pDst = (*pSrc - '0') << 4;
		}
		else
		{
			*pDst = (*pSrc - 'A' + 10) << 4;
		}

		pSrc++;

		// 输出低4位
		if ((*pSrc>='0') && (*pSrc<='9'))
		{
			*pDst |= *pSrc - '0';
		}
		else
		{
			*pDst |= *pSrc - 'A' + 10;
		}

		pSrc++;
		//TRACE("%s",pSrc);
		pDst++;
		//TRACE("%s",pDst);
	}

	// 返回目标数据长度
	return (nSrcLength / 2);
}

/**
 * function 可打印字符串转换为字节数据
 * 如：{0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01} --> "C8329BFD0E01"
 * 输入: pSrc - 源字符串指针
 * 		nSrcLength - 源字符串长度
 * 输出: pDst - 目标数据指针
 * 返回: 目标数据长度
 */

int SmtPlug::bytes2String(const uint8* pSrc, uint8* pDst, int nSrcLength)
{
	uint8 tmp[3];
	for(int i=0;i<nSrcLength;i++)
	{
		sprintf((char*)tmp, "%02x", pSrc[i]);
		memcpy(&pDst[2*i],tmp,2);
		//printf("%s",tmp);
	}
	//printf("\n%s",pDst);
	return (nSrcLength * 2);
}

uint8 SmtPlug::GetCount(uint8* pSrc)
{
	uint8 len=0;
	while(*pSrc++)
	{
		printf("%x ",*pSrc);
		len++;
	}

	return len;
}

/*
bool SmtPlug::lockTableWrite(myDatabase *pDB,string sTable)
{
	//return true;
	string sSql="LOCK TABLES ";
	sSql+=sTable;
	sSql+=" WRITE";

	if(!pDB->exec(sSql))
	{
		DBGMYSQL("%d ,%s failed",gettid(),sSql.c_str());
		exit(-1);
	}
	else
	{
		DBGMYSQL("%d ,%s success",gettid(),sSql.c_str());
	}

}


bool SmtPlug::lockTableRead(myDatabase *pDB,string sTable)
{
	//return true;
	string sSql="LOCK TABLES ";
	sSql+=sTable;
	sSql+=" Read";

	if(!pDB->exec(sSql))
	{
		DBGMYSQL("%d ,%s failed",gettid(),sSql.c_str());
		exit(-1);
	}
	else
	{
		DBGMYSQL("%d ,%s success",gettid(),sSql.c_str());
	}
}


bool SmtPlug::unlockTable(myDatabase *pDB )
{
//return true;
	string sSql="UNLOCK TABLES ";

	if(!pDB->exec(sSql))
	{
		DBGMYSQL("%d ,%s failed",gettid(),sSql.c_str());
		exit(-1);
	}
	else
	{
		DBGMYSQL("%d ,%s success",gettid(),sSql.c_str());
	}
}
*/
